package com.nineclock.auth.aop;

import com.nineclock.auth.entity.IntegrationAuthenticationEntity;
import com.nineclock.auth.entity.NcOauthTokenDTO;
import com.nineclock.auth.threadlocal.IntegrationAuthenticationHolder;
import com.nineclock.auth.threadlocal.UserHolder;
import com.nineclock.common.entity.Result;
import com.nineclock.common.entity.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 *
 * ProceedingJoinPoint: 连接点对象(aop拦截的方法)
 *
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 * @Version 1.0
 */
@Component
@Slf4j
@Aspect //配置切面
public class AuthTokenAspect {
    //从容器注入 请求对象
    @Autowired
    HttpServletRequest request;

    @Around("execution(* org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        try {
            //获取 认证类型
            String authType = request.getParameter("auth_type");
            //获取 所有参数的 map集合
            Map<String, String[]> parameterMap = request.getParameterMap();

            IntegrationAuthenticationEntity entity = new IntegrationAuthenticationEntity();
            entity.setAuthType(authType); //赋值  认证类型
            entity.setAuthParameters(parameterMap); //赋值 其他参数
            //存储到 当前线程
            IntegrationAuthenticationHolder.set(entity);
            //调用原始方法
            //resultObj 是原始方法的返回值
            Object resultObj = joinPoint.proceed();
            //把原始方法返回值 转换为实际类型
            ResponseEntity<OAuth2AccessToken> responseEntity = (ResponseEntity<OAuth2AccessToken>) resultObj;
            Result result = null;
            if( responseEntity.getStatusCode().is2xxSuccessful()){
                //获取相应实体的 body（具体的认证信息）
                OAuth2AccessToken oauth2AccessToken = responseEntity.getBody();

                //从当前线程取出userInfo
                UserInfo userInfo = UserHolder.get();

                NcOauthTokenDTO ncOauthTokenDTO = new NcOauthTokenDTO();
                ncOauthTokenDTO.setOauth2AccessToken(oauth2AccessToken); // Oauth2AccessToken
                ncOauthTokenDTO.setUser(userInfo); //userInfo
                //环绕后 增强
                result = Result.success(ncOauthTokenDTO);
            } else{
                result = Result.errorCodeMessage(401, "获取令牌失败!!");
            }

            return ResponseEntity.ok(result);
        } finally {

        }
    }
}
